package corestruct

import (
	"container/list"
	"sync"
)

type QueueT[T any] struct {
	list   *list.List
	locker sync.Mutex
}

func (p *QueueT[T]) Push(elem T) {
	p.locker.Lock()
	defer func() {
		p.locker.Unlock()
	}()
	if p.list == nil {
		p.list = list.New()
	}
	p.list.PushBack(elem)

}

//	func (p *QueueT[T]) Pop() T {
//		p.locker.Lock()
//		defer p.locker.Unlock()
//		if p.list == nil {
//			p.list = list.New()
//		}
//
//		if elem := p.list.Front(); elem != nil {
//			p.list.Remove(elem)
//			return elem.Value.(T)
//		}
//		return nil
//	}
func (p *QueueT[T]) PushList(l []T) {
	p.locker.Lock()
	defer p.locker.Unlock()
	if p.list == nil {
		p.list = list.New()
	}

	for _, v := range l {
		p.list.PushBack(v)
	}
}
func (p *QueueT[T]) PopAll(max int) []T {
	if max == 0 {
		max = 10000
	}
	var r = make([]T, 0)
	p.locker.Lock()
	defer p.locker.Unlock()
	if p.list == nil {
		p.list = list.New()
	}
	for {
		if elem := p.list.Front(); elem != nil {
			p.list.Remove(elem)
			r = append(r, elem.Value.(T))
			if len(r) >= max {
				break
			}
		} else {
			break
		}
	}

	return r
}

func (p *QueueT[T]) Count() int {
	p.locker.Lock()
	defer p.locker.Unlock()
	if p.list == nil {
		p.list = list.New()
	}
	return p.list.Len()
}
